<template>
  <div>
    <PageWrapper :contentFullHeight="true">
      <Row :gutter="24">
        <Col :xs="24" :sm="24" :md="24" :lg="4" :xl="4" style="background-color: white">
          <Tabs v-model:activeKey="activeKey">
            <TabPane key="1" :tab="t('routes.demo.partManager.productStructure')">
              <div class="tree-container">
                <BasicTree
                  :treeData="partData"
                  :toolbar="true"
                  :search="true"
                  @select="selectPart"
                  :beforeRightClick="rightClick"
                />
              </div>
            </TabPane>
            <!-- <TabPane key="2" tab="产品信息">2</TabPane> -->
          </Tabs>
        </Col>
        <Col
          :xs="24"
          :sm="24"
          :md="24"
          :lg="19"
          :xl="19"
          style="background-color: white; margin-left: 10px"
        >
          <Row>
            <Col :xs="24" :sm="24" :md="24" :lg="24" :xl="24">
              <exactQuery style="margin-top: 10px" />
            </Col>
          </Row>
          <Row>
            <Col :xs="24" :sm="24" :md="24" :lg="24" :xl="24">
              <BasicTable @register="registerTable">
                <template #toolbar>
                  <a-button type="primary" @click="CreatePart">
                    {{ t('common.create') }}
                  </a-button>
                </template>
                <!-- 代号 -->
                <template #name="{ text: name }">
                  <Row>
                    <Col :span="22" class="text-ellipsis">
                      <span>{{ name }}</span>
                    </Col>
                    <Col :span="2">
                      <Icon icon="ion:ios-copy-outline" color="#7a7374" @click="handleCopy(name)" />
                    </Col>
                  </Row>
                </template>
                <!-- 状态 -->
                <template #state="{ text: state, record }">
                  <span v-if="record.fileorpart === '1'">{{
                    proxy.$filters.filterPartStatus(state)
                  }}</span>
                  <span v-else-if="record.fileorpart === '0'">{{
                    proxy.$filters.filterDocumentStatus(state)
                  }}</span>
                </template>
                <!-- 创建时间 -->
                <template #creattime="{ text: creattime }">
                  <span>
                    {{ proxy.$filters.filterTime(creattime) }}
                  </span>
                </template>
                <!-- 文件/零件 -->
                <template #fileorpart="{ text: fileorpart }">
                  {{
                    fileorpart === '0'
                      ? t('routes.demo.partManager.file')
                      : t('routes.demo.partManager.part')
                  }}
                </template>
                <!-- 是否为关联文件 -->
                <template #isshortcut="{ text: isshortcut }">
                  {{ isshortcut === '0' ? t('common.no') : t('common.yes') }}
                </template>
                <!-- 操作 -->
                <template #action="{ record }">
                  <TableAction
                    :actions="[
                      // 零件
                      {
                        icon: 'ion:ios-download-outline',
                        tooltip: t('routes.demo.partManager.checkInPart'),
                        popConfirm: {
                          title: t('routes.demo.partManager.directCheckIn'),
                          placement: 'top',
                          confirm: checkInPart.bind(null, record),
                          cancel: unCheckInPart.bind(null, record),
                          okText: t('common.yes'),
                          cancelText: t('common.no'),
                        },
                        ifShow: record.fileorpart === '1' && record.state === '2',
                      },
                      {
                        icon: 'ion:ios-upload-outline',
                        tooltip: t('routes.demo.partManager.checkOutPart'),
                        popConfirm: {
                          title: t('routes.demo.partManager.directCheckOut'),
                          placement: 'top',
                          confirm: checkOutPart.bind(null, record),
                          cancel: unCheckOutPart.bind(null, record),
                          okText: t('common.yes'),
                          cancelText: t('common.no'),
                        },
                        ifShow: record.fileorpart === '1' && record.state === '1',
                      },
                      {
                        icon: 'ion:ios-redo-outline',
                        tooltip: t('routes.demo.partManager.revokePart'),
                        popConfirm: {
                          title: t('routes.demo.partManager.revokePartTip'),
                          placement: 'top',
                          confirm: revokePart.bind(null, record),
                        },
                        ifShow: record.fileorpart === '1' && record.state === '2',
                      },
                      {
                        icon: 'ant-design:delete-outlined',
                        tooltip: t('routes.demo.partManager.deletePart'),
                        color: 'error',
                        popConfirm: {
                          title: t('common.confirmDelete'),
                          confirm: DeletePart.bind(null, record),
                        },
                        ifShow: record.fileorpart === '1' && record.state === '1',
                      },
                      {
                        icon: 'ion:md-remove-circle-outline',
                        tooltip: t('routes.demo.partManager.scrapParts'),
                        color: 'error',
                        popConfirm: {
                          title: t('routes.demo.partManager.scrapPartsTip'),
                          confirm: abolishPart.bind(null, record),
                        },
                        ifShow: record.fileorpart === '1',
                      },
                      // 文件
                      {
                        icon: 'ion:ios-download-outline',
                        tooltip: t('routes.demo.partManager.checkInFile'),
                        popConfirm: {
                          title: t('routes.demo.partManager.directCheckInFile'),
                          placement: 'top',
                          confirm: checkInDoc.bind(null, record),
                          cancel: unCheckInDoc.bind(null, record),
                          okText: t('common.yes'),
                          cancelText: t('common.no'),
                        },
                        ifShow: record.fileorpart === '0' && record.state === '1',
                      },
                      {
                        icon: 'ion:ios-upload-outline',
                        tooltip: t('routes.demo.partManager.checkOutFile'),
                        popConfirm: {
                          title: t('routes.demo.partManager.directCheckOutFile'),
                          placement: 'top',
                          confirm: checkOutDoc.bind(null, record),
                          cancel: unCheckOutDoc.bind(null, record),
                          okText: t('common.yes'),
                          cancelText: t('common.no'),
                        },
                        ifShow: record.fileorpart === '0' && record.state === '8',
                      },
                      {
                        icon: 'ion:ios-redo-outline',
                        tooltip: t('routes.demo.partManager.revokeFile'),
                        popConfirm: {
                          title: t('routes.demo.partManager.revokeFileTip'),
                          placement: 'top',
                          confirm: revokeDoc.bind(null, record),
                        },
                        ifShow: record.fileorpart === '0' && record.state === '1',
                      },
                      {
                        icon: 'ant-design:delete-outlined',
                        tooltip: t('routes.demo.partManager.deleteFile'),
                        color: 'error',
                        popConfirm: {
                          title: t('routes.demo.partManager.deleteFileTip'),
                          placement: 'top',
                          confirm: DeleteFile.bind(null, record),
                        },
                        ifShow: record.fileorpart === '0' && record.state === '8',
                      },
                    ]"
                    :dropDownActions="[
                      // 共同的
                      // {
                      //   label: t('routes.demo.partManager.copyCode'),
                      //   onClick: handleCopy.bind(null, record),
                      // },
                      // 零件
                      {
                        label: t('routes.demo.partManager.modifyPart'),
                        onClick: EditPart.bind(null, record),
                        ifShow: record.fileorpart === '1',
                      },
                      {
                        label: t('routes.demo.partManager.productStructure'),
                        ifShow: record.fileorpart === '1',
                        onClick: handleStruct.bind(null, record),
                      },
                      {
                        label: t('routes.demo.partManager.uploadThumbnail'),
                        onClick: uploadPartImg.bind(null, record),
                        ifShow: record.fileorpart === '1',
                      },
                      {
                        label: t('routes.demo.partManager.structureComparison'),
                        onClick: handleContrast.bind(null, record),
                        ifShow: record.fileorpart === '1',
                      },
                      {
                        label: t('routes.demo.partManager.workAssignment'),
                        onClick: handleWorkHandOver.bind(null, record),
                        ifShow: record.fileorpart === '1',
                      },
                      {
                        label: t('routes.demo.partManager.useSituation'),
                        onClick: handleUseSituation.bind(null, record),
                        ifShow: record.fileorpart === '1',
                      },
                      {
                        label: t('routes.demo.partManager.partAssignObj'),
                        onClick: handlePartAssignObj.bind(null, record),
                        ifShow: record.fileorpart === '1',
                      },
                      {
                        label: t('routes.demo.partManager.versionShow'),
                        onClick: handleVersionShow.bind(null, record),
                        ifShow: record.fileorpart === '1',
                      },
                      {
                        label: t('routes.demo.partManager.relatedProcessInstance'),
                        ifShow: record.fileorpart === '1',
                      },
                      // 文件
                      {
                        label: t('routes.demo.partManager.viewFile'),
                        onClick: viewFile.bind(null, record),
                        ifShow: record.fileorpart === '0',
                      },
                      {
                        label: t('routes.demo.partManager.borrow'),
                        onClick: borrowFile.bind(null, record),
                        ifShow: record.fileorpart === '0',
                      },
                      {
                        label: t('routes.demo.partManager.browse'),
                        onClick: handleBrowse.bind(null, record),
                        ifShow: record.fileorpart === '0',
                      },
                      {
                        label: t('routes.demo.partManager.downloadFigureDoc'),
                        onClick: handleDownload.bind(null, record),
                        ifShow: record.fileorpart === '0',
                      },
                      {
                        label: t('routes.demo.partManager.associatedObject'),
                        onClick: handleAssociated.bind(null, record),
                        ifShow: record.fileorpart === '0',
                      },
                      {
                        label: t('routes.demo.partManager.workAssignment'),
                        onClick: handleAssign.bind(null, record),
                        ifShow: record.fileorpart === '0',
                      },
                    ]"
                  />
                </template>
              </BasicTable>
            </Col>
          </Row>
        </Col>
      </Row>
      <!-- 目录新增修改 -->
      <directoryModal @register="registerDireModal" @success="reloadGetDirectoryLevel" />
      <!-- 新增零件选择零件类型 -->
      <createPartTypeModal @register="registerCreatePartTypeModal" />
      <!-- 零件详情 -->
      <partDetailModal @register="registerPartDetailModal" />
      <!-- 图文档详情 -->
      <docDetail @register="registerDocDetailModal" />
      <!-- 检入检出流程 -->
      <initiateFlow @register="registerInitiateFlowModal" ref="AddWorkFlowForm" />
      <!-- 借阅流程 -->
      <selectForm @register="registerBorrowModal" />
      <!-- 关联，反关联弹窗 -->
      <assObjModal @register="registerAssociatedModal" @success="reload()" />
      <!-- 文件工作指派 -->
      <DocWorkAssign @register="registerDocWorkModal" @success="reload()" />
      <!-- 上传预览图 -->
      <uploadImg @register="registerUploadPartImgModal" @success="reload()" />
      <!-- 结构比较 -->
      <partContrast @register="registerPartContrastModal" />
      <!-- 零件工作指派 -->
      <partHandoverModal @register="registerPartHandoverModal" />
      <!-- 使用情况 -->
      <UseSituation @register="registerUseSituationModal" />
      <!-- 对象类绑定 -->
      <objBindModal @register="registerObjBindModal" />
      <!-- 目录权限设置 -->
      <permissionModal @register="registerPermissionModal" />
      <!-- 关联对象 -->
      <associatedParts @register="registerAssociatedPartsModal" />
      <!-- 版本展示 -->
      <versionShow @register="registerVersionShow" />
    </PageWrapper>
  </div>
</template>

<script lang="ts" setup>
  import { ref, getCurrentInstance, nextTick, provide } from 'vue';
  import { useRouter } from 'vue-router';
  import { PageWrapper } from '/@/components/Page';
  import { Row, Col, Tabs, TabPane } from 'ant-design-vue';
  import { BasicTable, useTable, TableAction } from '/@/components/Table';
  import { BasicTree } from '/@/components/Tree/index';
  import { useMessage } from '/@/hooks/web/useMessage';
  import { useModal } from '/@/components/Modal';
  import { useI18n } from '/@/hooks/web/useI18n';
  import { getPartColumns } from './tableData';
  import throttle from 'lodash/throttle';
  import { Base64 } from 'js-base64';
  import { Icon } from '/@/components/Icon';

  import {
    getDirectoryLevel,
    getPrdFolder,
    deletePrdFolder,
    checkIn,
    checkOut,
    cancelFile,
    deleteFile,
    browseFile,
    downloadFile,
    getWorkAssignList,
  } from '/@/api/demo/document';
  import {
    getPartData,
    PartJustCheckIn,
    PartJustCheckOut,
    RevokePart,
    DeleteAllVersionFile,
    PartCanAddWorkflowIns,
  } from '/@/api/demo/partManager';
  import { getBorrowBdDataJudge } from '/@/api/demo/knowledge';

  import directoryModal from '../documentManager/directoryModal.vue';
  import createPartTypeModal from './createPartTypeModal.vue';
  import partDetailModal from './partDetailModal.vue';
  import docDetail from '../documentManager/docDetail.vue';
  import initiateFlow from '../workFlow/initiateFlow.vue';
  import selectForm from '../formManager/selectForm.vue';
  import assObjModal from '../documentManager/assObjModal.vue';
  import DocWorkAssign from '../documentManager/DocWorkAssign.vue';
  import uploadImg from './uploadImg.vue';
  import partContrast from './partContrast.vue';
  import partHandoverModal from './partHandoverModal.vue';
  import UseSituation from './UseSituation.vue';
  import objBindModal from '../documentManager/objBindModal.vue';
  import permissionModal from '/@/views/demo/documentManager/components/permissionModal.vue';
  import associatedParts from './components/associatedParts.vue';
  import versionShow from './components/versionShow.vue';

  // 模糊、精确查询
  import exactQuery from '../../components/exactQuery.vue';

  // 初始化赋值
  const { t } = useI18n();
  const router = useRouter();
  const { createMessage } = useMessage();
  const { proxy }: any = getCurrentInstance();
  const activeKey = ref('1');
  const selectedPartKey = ref<string>('');
  const partSuperId = ref<number>(0);
  const partData = ref<any>([]);
  const AddWorkFlowForm = ref<any>(null);

  const handleReload = () => {
    reload();
  };

  provide('reload', { handleReload });

  // 接口
  getDirectoryLevel(partSuperId.value).then((res) => {
    partData.value = res;
  });

  const reloadGetDirectoryLevel = () => {
    getDirectoryLevel(partSuperId.value).then((res) => {
      nextTick(() => {
        partData.value = res;
      });
    });
  };

  // 方法
  const selectPart = (selectedKeys) => {
    selectedPartKey.value = selectedKeys[0];
    reload();
  };

  const rightClick = (node) => {
    const arr = [
      {
        label: t('routes.demo.documentWorkPlace.basicFunction'),
        children: [
          {
            label: t('common.create'),
            handler: () => {
              openDireModal(true, { treeKey: node.eventKey, isUpdate: false });
            },
          },
          {
            label: t('common.edit'),
            handler: () => {
              getPrdFolder(node.eventKey).then((res) => {
                openDireModal(true, { treeKey: node.eventKey, isUpdate: true, res });
              });
            },
          },
          {
            label: t('common.delete'),
            handler: () => {
              deletePrdFolder(node.eventKey).then(() => {
                reloadGetDirectoryLevel();
                createMessage.success(t('common.delSuccessText'));
              });
            },
          },
          {
            label: t('common.copy'),
          },
          {
            label: t('common.paste'),
          },
        ],
      },
      {
        label: t('routes.demo.documentWorkPlace.set'),
        children: [
          {
            label: t('routes.demo.documentWorkPlace.permission'),
            handler: () => {
              openDirePermissionModal(true, { treeKey: node.eventKey });
            },
          },
          {
            label: t('routes.demo.documentWorkPlace.objectClassBind'),
            handler: () => {
              openObjBindModal(true, { treeKey: node.eventKey });
            },
          },
        ],
      },
    ];
    return arr;
  };

  // 新建零件
  const CreatePart = () => {
    if (selectedPartKey.value === '') {
      createMessage.warning(t('routes.demo.partManagerSettings.directoryPlaceholder'));
    } else {
      openCreatePartTypeModal(true, { FolderId: selectedPartKey.value });
    }
  };
  // 直接检入零件
  const checkInPart = (record: Recordable) => {
    PartJustCheckIn(record.id).then(() => {
      reload();
      createMessage.success(t('routes.demo.partManager.checkInPartSuccess'));
    });
  };
  // 检入零件
  const unCheckInPart = (record: Recordable) => {
    PartCanAddWorkflowIns(record.id, record.version, '检入').then((res) => {
      if (res) {
        AddWorkFlowForm.value.lcShow(record, 'jr', '', '', '', '', '', record.id);
      } else {
        createMessage.warning(t('routes.demo.partManager.notFitCheckInCondition'));
      }
    });
  };
  // 直接检入文件
  const checkInDoc = (record: Recordable) => {
    checkIn(record.id).then(() => {
      reload();
      createMessage.success(t('common.checkInSuccessText'));
    });
  };
  // 检入文件
  const unCheckInDoc = (record: Recordable) => {
    AddWorkFlowForm.value.lcShow(record, 'jr', '', '', '', '', '', record.id);
  };

  // 直接检出零件
  const checkOutPart = (record: Recordable) => {
    PartJustCheckOut(record.id, record.version).then(() => {
      reload();
      createMessage.success(t('routes.demo.partManager.checkOutPartSuccess'));
    });
  };
  // 检出零件
  const unCheckOutPart = (record: Recordable) => {
    PartCanAddWorkflowIns(record.id, record.version, '检出').then((res) => {
      if (res) {
        AddWorkFlowForm.value.lcShow(record, 'jc', '', '', '', '', '', record.id);
      } else {
        createMessage.warning(t('routes.demo.partManager.notFitCheckOutCondition'));
      }
    });
  };

  // 直接检出文件
  const checkOutDoc = (record: Recordable) => {
    checkOut(record.id).then(() => {
      reload();
      createMessage.success(t('common.checkOutSuccessText'));
    });
  };

  // 检出文件
  const unCheckOutDoc = (record: Recordable) => {
    AddWorkFlowForm.value.lcShow(record, 'jc', '', '', '', '', '', record.id);
  };

  // 撤销零件
  const revokePart = (record: Recordable) => {
    RevokePart(record.id).then(() => {
      reload();
      createMessage.success(t('common.undoSuccessText'));
    });
  };

  // 撤销文件
  const revokeDoc = (record: Recordable) => {
    cancelFile(record.id).then(() => {
      reload();
      createMessage.success(t('common.undoSuccessText'));
    });
  };

  // 删除零件
  const DeletePart = (record: Recordable) => {
    DeleteAllVersionFile(record.id).then(() => {
      reload();
      createMessage.success(t('common.delSuccessText'));
    });
  };

  // 删除文件
  const DeleteFile = (record: Recordable) => {
    deleteFile(record.id).then(() => {
      reload();
      createMessage.success(t('common.delSuccessText'));
    });
  };

  // 废止零件
  const abolishPart = (record: Recordable) => {
    PartCanAddWorkflowIns(record.id, record.version, '废止').then((res) => {
      if (res) {
        AddWorkFlowForm.value.lcShow(record, 'fz', '', '', '', '', '', record.id);
      } else {
        createMessage.warning(t('routes.demo.partManager.notFitRevokeCondition'));
      }
    });
  };

  // 复制代号
  const handleCopy = (name) => {
    navigator.clipboard.writeText(name).then(() => {
      createMessage.success(t('common.copySuccessText'));
    });
  };

  // 查看文件
  const viewFile = (record: Recordable) => {
    openDocDetailModal(true, record);
  };

  // 借阅文件
  const borrowFile = (record: Recordable) => {
    getBorrowBdDataJudge().then((res) => {
      if (res === '1') {
        if (record.state === '8') {
          const param = {
            record: record,
            currentDireId: selectedPartKey.value,
          };
          openBorrowModal(true, param);
        } else {
          createMessage.error(t('routes.demo.documentManager.onlyBorrowAble'));
        }
      } else {
        const param = {
          record: record,
          currentDireId: selectedPartKey.value,
        };
        openBorrowModal(true, param);
      }
    });
  };

  // 浏览文件
  const handleBrowse = throttle((record: Recordable) => {
    try {
      setLoading(true);
      browseFile(record.id, record.version).then((res) => {
        let url = res[0]; //要预览文件的访问地址
        const innerWidth = (window.innerWidth - 1000) / 2;
        const innerHeight = (window.innerHeight - 600) / 2;
        const windowFeatures = `left=${innerWidth},top=${innerHeight},width=1000,height=600`;
        window.open(
          res.data.result[1] + ':8012/onlinePreview?url=' + encodeURIComponent(Base64.encode(url)),
          'mozillaWindow',
          windowFeatures,
        );
      });
    } finally {
      setLoading(false);
    }
  }, 3000);

  // 下载图档
  const handleDownload = throttle((record: Recordable) => {
    downloadFile(record.id, record.version, record.filename).then(() => {
      createMessage.success(t('common.downLoadSuccess'));
    });
  }, 3000);

  // 关联对象
  const handleAssociated = () => {
    openAssociatedModal(true, { isAssociation: true, selectedDirKey: selectedPartKey.value });
  };

  // 工作指派
  const handleAssign = (record: Recordable) => {
    if (record.state !== '1') {
      createMessage.error(t('routes.demo.documentManager.objectNotCheckout'));
    } else {
      getWorkAssignList(record.id, '0').then((res) => {
        openDocWorkModal(true, { recordData: record, workAssignList: res });
      });
    }
  };

  // 零件工作指派
  const handleWorkHandOver = (record: Recordable) => {
    if (record.state !== '2') {
      createMessage.error(t('routes.demo.documentManager.objectNotCheckout'));
    } else {
      getWorkAssignList(record.id, '0').then((res) => {
        openPartWorkHandOverModal(true, { recordData: record, workAssignList: res });
      });
    }
  };

  // 使用情况
  const handleUseSituation = (record: Recordable) => {
    openUseSituationModal(true, record);
  };

  // 关联对象
  const handlePartAssignObj = (record: Recordable) => {
    openAssociatedPartsModal(true, record);
  };

  // 版本展示
  const handleVersionShow = (record: Recordable) => {
    openVersionShowModal(true, record);
  };

  // 上传缩略图
  const uploadPartImg = (record: Recordable) => {
    openUploadPartImgModal(true, record);
  };

  // 修改零件
  const EditPart = (record: Recordable) => {
    openPartDetailModal(true, {
      isUpdate: true,
      FolderId: selectedPartKey.value,
      partType: record.type,
      currentRecord: record,
    });
  };

  // 产品结构
  const handleStruct = (record: Recordable) => {
    router.push({ name: 'productStructure', params: { id: record.id, version: record.version } });
  };

  // 结构比较
  const handleContrast = (record: Recordable) => {
    openContrastModal(true, record);
  };

  // 初始化表格
  const [registerTable, { reload, setLoading }] = useTable({
    api: getPartData,
    beforeFetch: () => {
      return selectedPartKey.value;
    },
    columns: getPartColumns(),
    bordered: true,
    showIndexColumn: false,
    showTableSetting: true, // 显示表格设置工具
    tableSetting: { fullScreen: true }, // 表格设置工具配置
    // pagination: { pageSize: 5, pageSizeOptions: ['5', '10', '15', '20'], defaultPageSize: 5 },
    canResize: true,
    isTreeTable: true,
    childrenColumnName: 'sonpfi',
    rowKey: 'id',
    actionColumn: {
      width: 200,
      title: t('common.action'),
      dataIndex: 'action',
      slots: { customRender: 'action' },
    },
  });

  // 目录弹窗
  const [registerDireModal, { openModal: openDireModal }] = useModal();
  // 新增零件选择零件类型
  const [registerCreatePartTypeModal, { openModal: openCreatePartTypeModal }] = useModal();
  // 零件详情
  const [registerPartDetailModal, { openModal: openPartDetailModal }] = useModal();
  // 图文档详情
  const [registerDocDetailModal, { openModal: openDocDetailModal }] = useModal();
  // 检入检出流程
  const [registerInitiateFlowModal] = useModal();
  // 借阅流程弹窗
  const [registerBorrowModal, { openModal: openBorrowModal }] = useModal();
  // 关联，反关联弹窗
  const [registerAssociatedModal, { openModal: openAssociatedModal }] = useModal();
  // 文档工作指派
  const [registerDocWorkModal, { openModal: openDocWorkModal }] = useModal();
  // 上传预览图
  const [registerUploadPartImgModal, { openModal: openUploadPartImgModal }] = useModal();
  // 结构比较
  const [registerPartContrastModal, { openModal: openContrastModal }] = useModal();
  // 零件工作指派
  const [registerPartHandoverModal, { openModal: openPartWorkHandOverModal }] = useModal();
  // 使用情况
  const [registerUseSituationModal, { openModal: openUseSituationModal }] = useModal();
  // 目录权限设置
  const [registerPermissionModal, { openModal: openDirePermissionModal }] = useModal();
  // 对象类绑定设置弹窗
  const [registerObjBindModal, { openModal: openObjBindModal }] = useModal();
  // 零件对象关联
  const [registerAssociatedPartsModal, { openModal: openAssociatedPartsModal }] = useModal();
  // 版本展示
  const [registerVersionShow, { openModal: openVersionShowModal }] = useModal();
</script>

<style lang="less" scope>
  .text-ellipsis {
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
  }

  .tree-container {
    height: 700px;
    overflow-y: auto;
  }
</style>
